package kim.artemis.rpc.core.protocol.client;

import kim.artemis.rpc.core.model.ArtemisRpcFutureResponse;
import kim.artemis.rpc.core.model.ArtemisRpcResponse;
import kim.artemis.rpc.core.registry.ServiceRegistry;
import kim.artemis.rpc.core.registry.ZookeeperServiceRegistry;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * 调用程序工厂
 * @author Wq.
 */
@Slf4j
public class ArtemisRpcClientInvoker {

    @Getter
    private static ArtemisRpcClientInvoker invokerFactory = new ArtemisRpcClientInvoker(ZookeeperServiceRegistry.class);

    /**
     * 注册中心
     */
    private Class<? extends ServiceRegistry> registryCenter;


    @Getter
    public ServiceRegistry serviceRegistry;

    /**
     * 初始化未来的响应池
     */
    private ConcurrentMap<Long, ArtemisRpcFutureResponse> futureResponsePool = new ConcurrentHashMap<>();

    public ArtemisRpcClientInvoker(Class<? extends ServiceRegistry> registryCenter) {
        this.registryCenter = registryCenter;
    }

    /**
     * 启动服务
     * @param address
     */
    public void start (String address) {
        if (null != registryCenter) {
            try {
                serviceRegistry = registryCenter.newInstance();
                serviceRegistry.start(address);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 停止服务
     */
    public void stop () {
        if (null == serviceRegistry) {
            serviceRegistry.stop();
        }
    }

    /**
     * 推送到未来响应池
     * @param artemisId
     * @param futureResponse
     */
    public void pushInvokerFuture (long artemisId, ArtemisRpcFutureResponse futureResponse) {
        futureResponsePool.put(artemisId, futureResponse);
    }

    /**
     * 根据请求编号从响应池中删除相应数据
     * @param artemisId
     */
    public void removeInvokerFuture (long artemisId) {
        futureResponsePool.remove(artemisId);
    }

    /**
     * 通知调用者未来的
     * @param artemisId
     * @param artemisRpcResponse
     */
    public void notifyInvokerFuture(long artemisId, final ArtemisRpcResponse artemisRpcResponse){
        // 获取未来响应
        final ArtemisRpcFutureResponse futureResponse = futureResponsePool.get(artemisId);
        if (null == futureResponse) {
            return;
        }
        futureResponse.setArtemisRpcResponse(artemisRpcResponse);
        // 删除相关响应
        futureResponsePool.remove(artemisId);
    }

}
